#pragma once
#include <QOpenGLFunctions_4_5_Core>

class RenderUtility : protected QOpenGLFunctions_4_5_Core {
public:
    RenderUtility() {
        initializeOpenGLFunctions();
    }

    void renderScreenQuad() {
        static GLfloat Fvert[] = { -1,-1,0,  1,-1,0,  1,1,0,  -1,1,0 };
        static GLfloat Ftcoord[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
        static GLuint  Find[] = { 0,1,2,  0,2,3 };
        static GLuint FindexVBO = 0, FVAO = 0, FvertTexVBO = 0;
        static bool FfirstTime = true;

        if (FfirstTime) {
            FfirstTime = false;

            glGenVertexArrays(1, &FVAO);
            glBindVertexArray(FVAO);

            glGenBuffers(1, &FindexVBO);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, FindexVBO);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Find), Find, GL_STATIC_DRAW);

            glGenBuffers(1, &FvertTexVBO);
            sendVertsTexToGPU(FvertTexVBO, Fvert, Ftcoord, sizeof(Fvert), sizeof(Ftcoord));

            glBindBuffer(GL_ARRAY_BUFFER, FvertTexVBO);
            glEnableVertexAttribArray(0);
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
            glEnableVertexAttribArray(1);
            glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)sizeof(Fvert));

            glBindVertexArray(0);
        }

        glBindVertexArray(FVAO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, FindexVBO);

        const GLboolean cullingWasEnabled = glIsEnabled(GL_CULL_FACE);
        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);

        if (!cullingWasEnabled) {
            glDisable(GL_CULL_FACE);
        }

        glBindVertexArray(0);
    }


    void useDefaultVAO(void)
    {
        static GLuint gDefaultVAO = 0;

        if (!gDefaultVAO)
            glGenVertexArrays(1, &gDefaultVAO);

        glBindVertexArray(gDefaultVAO);
    }

private:
    void sendVertsTexToGPU(GLuint vertTexVBO, GLfloat vert[], GLfloat tcoord[], int svert, int stcoord) {
        glBindBuffer(GL_ARRAY_BUFFER, vertTexVBO);
        glBufferData(GL_ARRAY_BUFFER, svert + stcoord, nullptr, GL_STATIC_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER, 0, svert, vert);
        glBufferSubData(GL_ARRAY_BUFFER, svert, stcoord, tcoord);
    }
};
